﻿/*
 * Module Name: Math Extensions.cs
 * 
 * Purpose: This class is used to store commonly used functions
 * 
 * Created by: Chris Tisdale
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Common_Code.Math_Extensions
{
    public class MathExtensions
    {
        /*
         * Name: Factor
         * 
         * Parameters: double[] function
         * 
         * Returns: double[]
         * 
         * Purpose: 
         */
        public static double[] Factor(double[] function)
        {
            throw new NotImplementedException();
        }

        /*
         * Name: FindPrimes
         * 
         * Parameters: long val
         * 
         * Returns: int[]
         * 
         * Purpose: 
         */
        public static int[] FindPrimes(long val)
        {
            throw new NotImplementedException();
        }

        /*
         * Name: KnapsackProblem
         * 
         * Parameters: T size
         *             T
         * 
         * Returns: T[]
         * 
         * Purpose: 
         */
        public static double[] KnapsackProblem<T>(T size, T[] vars)
        {
            throw new NotImplementedException();
        }

        /*
         * Name: CalcTotal
         * 
         * Parameters: List<double> vals
         * 
         * Returns: double
         * 
         * Purpose: Calculates the total on an array of doubles
         */
        public static double CalcTotal(List<double> vals)
        {
            var total = 0.0;
            foreach (var val in vals)
            {
                total += val;
            }
            return total;
        }

        /*
         * Name: Factoral
         * 
         * Parameters: double x
         * 
         * Returns: double
         * 
         * Purpose: Gets the factoral of X
         */
        public static long Factoral(int x)
        {
            return ((x <= 1) ? 1 : (x * Factoral(x - 1)));
        }

        /*
         * Name: LinearInterpolation
         * 
         * Parameters: double x0
         *             double x1
         *             double y0
         *             double y1
         *             double y
         * 
         * Returns: double
         * 
         * Purpose: This will calculate the Linear Interpolation for a given value
         */
        public static double LinearInterpolation(double x0, double x1, double y0, double y1, double x)
        {
            var y = y0 + ((y1 - y0) / (x1 - x0)) * (x - x0);
            return y;
        }

        /*
         * Name: DividedDifferences
         * 
         * Parameters: 
         * 
         * Returns: double
         * 
         * Purpose: 
         */
        public static double DividedDifferences(double[] xi, double[] fi, double x)
        {
            var temp = new Backwards_Difference(xi, fi);
            return temp.GetInterpolationAt(x);
        }

        /*
         * Name: ForwardDifferences
         * 
         * Parameters: 
         * 
         * Returns: double
         * 
         * Purpose: 
         */
        public static double ForwardDifferences(double[] xi, double[] fi, double x)
        {
            var temp = new Forward_Differences(xi, fi);
            return temp.GetInterpolationAt(x);
        }

        /*
         * Name: LagrangeInterpolation
         * 
         * Parameters: double[] xi
         *             double[] fi
         *             double x
         * 
         * Returns: double
         * 
         * Purpose: This will generate a Lagrange Polynomial and calculate the value at x
         */
        public static double LagrangeInterpolation(double[] xi, double[] fi, double x)
        {
            if (xi == null || fi == null || xi.Length != fi.Length || xi.Length == 0 || fi.Length == 0)
                throw new ArgumentException("The array sizes don't match");
            double val = 0, temp = 0;
            var count = 0;
            for (var i = 0; i <= fi.Length; i++)
            {
                if (i == 0)
                    count = 1;
                while (count < fi.Length)
                {
                    temp *= (x - xi[count]) / (xi[i] - xi[count]);
                    count++;
                    if (count == i)
                        count++;
                }
                count = 0;
                val += fi[i] * temp;
            }
            return val;
        }

        /*
         * Name: HermiteInterpolation
         * 
         * Parameters: 
         * 
         * Returns: double
         * 
         * Purpose: 
         */
        public static double HermiteInterpolation()
        {
            throw new NotImplementedException();
        }
    }
}
